package cn.tedu.mm.admin.section.filter;


import cn.tedu.mm.admin.section.dao.cache.IUserCacheRepository;
import cn.tedu.mm.common.enumerator.ServiceCode;
import cn.tedu.mm.common.pojo.authentication.CurrentPrincipal;
import cn.tedu.mm.common.pojo.po.UserStatePO;
import cn.tedu.mm.common.web.JsonResult;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * 解析JWT的过滤器，主要负责：
 * 1.尝试接收客户端携带的JWT
 * 2.尝试解析客户端携带的JWT
 * 3.将认证好的用用户数据（）用于创建Authentication对象，并存入到SecurityContext中
 */

@Component
public class JwtAuthorizationFilter extends OncePerRequestFilter {


    @Value("${mm.jwt.secret-key}")
    String secretKey;
    @Resource
    IUserCacheRepository iUserCacheRepository;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        System.out.println("开始处理");

        String jwt = request.getHeader("Authorization");



        //检测jwt基本有效性
        if (jwt == null) {
            filterChain.doFilter(request, response);
            return;
        }


        response.setContentType("application/json; charset=utf-8");
        //解析JWT
        Claims claims = null;
        try {
            String secretKey = this.secretKey;
            claims = Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(jwt)
                    .getBody();
        } catch (ExpiredJwtException | UnsupportedJwtException | MalformedJwtException e) {
            throw new RuntimeException(e);
        } catch (SignatureException e) {
            throw new RuntimeException(e);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException(e);
        }

        //获取jwt中的用户信息
        Long id = claims.get("id", Long.class);
        String username = claims.get("username", String.class);

        //获取IP地址和浏览器信息
        String addr = claims.get("remoteAddr", String.class);
        String agent = claims.get("userAgent", String.class);

        //获取当前IP地址和浏览器信息
        String remoteAddr = request.getRemoteAddr(); // IP地址
        String userAgent = request.getHeader("User-Agent"); // 浏览器信息

        if (!(addr.equals(remoteAddr)||agent.equals(userAgent))){

            String message = "请重新登录";
            JsonResult jsonResult = JsonResult.fail(
                    ServiceCode.ERROR_UNAUTHORIZED_DISABLED, message);
            String jsonString = JSON.toJSONString(jsonResult);
            PrintWriter writer = response.getWriter();
            writer.println(jsonString);
            iUserCacheRepository.deleteUserState(id);
            return;

        }



        //创建当事人
        CurrentPrincipal principal = new CurrentPrincipal()
                .setId(id)
                .setUsername(username);

        //从redis中获取用户状态
        UserStatePO userStatePO = iUserCacheRepository.getUserState(id);
        if (userStatePO == null) {
            filterChain.doFilter(request, response);
            return;
        }

        //获取账号激活状态
        Integer i = userStatePO.getEnable();
        System.out.println(i);
        if (i == 0) {
            String message = "操作失败，您的账号已经被禁用！";
            JsonResult jsonResult = JsonResult.fail(
                    ServiceCode.ERROR_UNAUTHORIZED_DISABLED, message);
            String jsonString = JSON.toJSONString(jsonResult);
            PrintWriter writer = response.getWriter();
            writer.println(jsonString);
            iUserCacheRepository.deleteUserState(id);
            return;
        }


        String jsonString = userStatePO.getAuthoritiesJsonString();
        List<String> strings = JSON.parseArray(jsonString, String.class);


        iUserCacheRepository.renewal(id);

        //创建权限列表
        ArrayList<SimpleGrantedAuthority> authorities = new ArrayList<>();
        strings.forEach(s -> {
            SimpleGrantedAuthority authority = new SimpleGrantedAuthority(s);
            authorities.add(authority);
        });


        //传入认证信息
        Authentication authenticationToken =
                new UsernamePasswordAuthenticationToken(principal, null, authorities);
        SecurityContext context = SecurityContextHolder.getContext();
        context.setAuthentication(authenticationToken);


        filterChain.doFilter(request, response);
    }
}
